#include "Quadrique.h"
#include "stdafx.h"

Quadrique::Quadrique(): Objet(){}

Quadrique::Quadrique(float aa, float bb, float cc, float dd, float ee, float ff,
					 float gg, float hh, float ii, float jj, Point centre1):
					 a(aa), b(bb), c(cc), d(dd), e(ee), f(ff), g(gg), h(hh), i(ii), j(jj), centre(centre1)
{}
					 
Quadrique::~Quadrique(){}

bool Quadrique::intersection(Rayon r) {

	Vecteur directionRayon = r.getDirection();
	Point origineRayon = r.getOrigine();

	float xC = centre.getX(), yC = centre.getY(), zC = centre.getZ();
	float xO = origineRayon.getX()-xC, yO = origineRayon.getY()-yC, zO = origineRayon.getZ()-zC;
	float xD = directionRayon.getX(), yD = directionRayon.getY(), zD = directionRayon.getZ();
	
	float A = a*xD*xD + b*yD*yD + c*zD*zD + 2*d*yD*zD + 2*e*xD*zD + 2*f*yD*xD;
	float B = 2*(a*xO*xD + b*yO*yD + c*zO*zD) 
		+ 2*d*(zO*yD+yO*zD) + 2*e*(xO*zD+zO*xD) + 2*f*(yO*xD+xO*yD) 
		+ g*xD + h*yD + i*zD;
	float C = a*xO*xO + b*yO*yO + c*zO*zO
		+ 2*d*zO*yO + 2*e*xO*zO + 2*f*yO*xO
		+ g*xO + h*yO + i*zO
		+ j;
	float t;
	if (A==0) {
		float w= -C/B;
		if(w >0)
			t=w;
	}
	else {
		float delta = B*B - 4.0f*A*C;
		if (delta<0) {
			return false;
		}
		float deltaSQRT = sqrt(delta);
		float t0 = (-B-deltaSQRT)/(2.0f*A);
		float t1 = (-B+deltaSQRT)/(2.0f*A);
		if (t0 < 0 && t1 < 0) {
			return false;
		}
		if (t0 == t1) {
			t=t0;
		}
		else if (t0 > 0 && t1 > 0) {
			t=t0<=t1?t0:t1;
		}
		else {
			return false;
		}
	}
	
	Point m = Point(r.getOrigine().getX()+xD*t, r.getOrigine().getY()+yD*t, r.getOrigine().getZ()+zD*t, 1);
	inter.setPoint(m);
	
	Vecteur normal (2*a*(m.getX()-xC) + 2*f*(m.getY()-yC) + 2*e*(m.getZ()-zC) + g,
					2*b*(m.getY()-yC) + 2*d*(m.getZ()-zC) + 2*f*(m.getX()-xC) + h,
					2*c*(m.getZ()-zC) + 2*e*(m.getX()-xC) + 2*d*(m.getY()-yC) + i);
	normal.normalize();
	if (normal.produitScalaire(directionRayon) > 0) {
		normal = normal* -1;
	}
	inter.setNormale(normal);
	inter.setT(t);
	return true;
}

BoiteEnglobante Quadrique::getBoite()
{
	BoiteEnglobante b;
    
	b.corner1.setX(centre.getX());
	b.corner1.setY(centre.getY());
	b.corner1.setZ(centre.getZ());

	b.corner2.setX(centre.getX());
	b.corner2.setY(centre.getY());
	b.corner2.setZ(centre.getZ());	
    
	return b;
}

bool Quadrique::aBoite()
{
	return false;
}

